package configs

import (
	"fmt"
	"github.com/chartmuseum/helm-push/pkg/chartmuseum"
	"github.com/kataras/iris/v12"
	apis2 "gluenet/pkg/apis"
	"gluenet/pkg/meta"
	"io"
	"mime/multipart"
	"os"
	"path/filepath"
)

func CreateConfig(ctx *apis2.GlueContext) {
	var (
		err error
		req = struct {
			Kind   string      `json:"kind"`
			Mode   string      `json:"mode"`
			Config meta.Config `json:"config"`
		}{}
	)
	if err = ctx.WebContext.ReadJSON(&req); err != nil {
		ctx.WebContext.JSON(apis2.ResponseReqErr(err, nil))
		return
	}

	ctx.Logger.Debugf("received add config")

	//校验数据
	if err = ctx.Validate.Struct(req.Config.ConfigValue, req.Mode, req.Kind); err != nil {
		ctx.Logger.Errorf("validate config %v", err)
		ctx.WebContext.JSON(apis2.ResponseReqErr(fmt.Errorf("validate config %v", err), nil))
		return
	}

	// 存储数据
	if _, err = ctx.DataBase.MetaDB().InsertOne(req.Config); err != nil {
		ctx.Logger.Errorf("impl config %v", err)
		ctx.WebContext.JSON(apis2.ResponseReqErr(fmt.Errorf("impl config %v", err), nil))
		return
	}

	ctx.WebContext.JSON(apis2.ResponseOK(nil))
}

const deleteConfig = "delete from config where label = ?"

func DeleteConfig(ctx *apis2.GlueContext) {
	var (
		err  error
		key  string
		kind string
		mode string
	)
	key = ctx.WebContext.URLParam("label")
	//kind = ctx.WebContext.URLParam("kind")
	mode = ctx.WebContext.URLParam("mode")

	ctx.Logger.Debugf("get config Label: %v", key)

	//校验label格式
	if err = ctx.Validate.Label(key, kind, mode, meta.KindConfig); err != nil {
		e := fmt.Errorf("validate label %v", err)
		ctx.WebContext.JSON(apis2.ResponseReqErr(e, nil))
		ctx.Logger.Errorf("%v", e)
		return
	}

	//删除数据
	if err = ctx.DataBase.ConfigDel(key); err != nil {
		e := fmt.Errorf("delete config %v", err)
		ctx.Logger.Errorf("%v", e)
		ctx.WebContext.JSON(apis2.ResponseReqErr(e, nil))
		return
	}
	if _, err = ctx.DataBase.MetaDB().Exec(deleteConfig, key); err != nil {
		ctx.Logger.Errorf("%v", err)
		ctx.WebContext.JSON(apis2.ResponseReqErr(fmt.Errorf("query error:%v, or data is nil", err), nil))
		return
	}

	//返回结果
	n, _ := ctx.WebContext.JSON(apis2.ResponseOK(nil))
	ctx.Logger.Debugf("get application response bytes: %v", n)
}

func CreateHelmConfig(ctx *apis2.GlueContext) {
	ctx.Logger.Debugf("recive uploads")
	//if _, err := ctx.WebContext.FormFile("/tmp/.uploads"); err != nil {
	//	ctx.WebContext.JSON(apis2.ResponseReqErr(err, nil))
	//	return
	//}
	//ctx.WebContext.JSON(apis2.ResponseOK(nil))
	file, info, err := ctx.WebContext.FormFile("file")
	if err != nil {
		iris.New().Logger().Info(err.Error())
		ctx.WebContext.JSON(iris.Map{
			"status":  "0",
			"type":    "0",
			"message": "文件上传失败!",
		})
		return
	}
	//最后要关闭文件
	defer file.Close()

	//获取文件名称`
	fname := info.Filename
	//把文件上传到哪里
	out, err := os.OpenFile("/tmp/"+fname, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		iris.New().Logger().Info(err.Error())
		ctx.WebContext.JSON(iris.Map{
			"status":  "0",
			"type":    "0",
			"message": "文件位置打开失败!",
		})
		return
	}

	//我们打印一下文件路径
	iris.New().Logger().Info("文件路径：" + out.Name())
	//最终也不要忘记关闭上传之后的文件流
	defer out.Close()

	//拷贝文件到指定位置
	_, err = io.Copy(out, file)
	if err != nil {
		ctx.WebContext.JSON(iris.Map{
			"status":  "0",
			"type":    "0",
			"message": "文件上传彻底失败!",
		})
		return
	}

	cli, err := chartmuseum.NewClient(chartmuseum.URL("http://10.102.85.29:8080"))
	if err != nil {
		ctx.WebContext.JSON(apis2.ResponseInterErr(fmt.Errorf("helm client failed %v", err), nil))
		return
	}

	_, err = cli.UploadChartPackage("/tmp/"+fname, false)
	if err != nil {
		ctx.WebContext.JSON(apis2.ResponseInterErr(fmt.Errorf("helm push failed %v", err), nil))
		return
	}
	ctx.WebContext.JSON(apis2.ResponseOK("ok"))
}

func saveUploadedFile(fh *multipart.FileHeader, destDirectory string) (int64, error) {
	src, err := fh.Open()
	if err != nil {
		return 0, err
	}
	defer src.Close()
	out, err := os.OpenFile(filepath.Join(destDirectory, fh.Filename),
		os.O_WRONLY|os.O_CREATE, os.FileMode(0666))
	if err != nil {
		return 0, err
	}
	defer out.Close()
	return io.Copy(out, src)
}

func CreateHelmUpdate(ctx *apis2.GlueContext) {
	if err := ctx.DataBase.HelmRepoUpdates(); err != nil {
		ctx.WebContext.JSON(apis2.ResponseInterErr(fmt.Errorf("helm push failed %v", err), nil))
		return
	}
	ctx.WebContext.JSON(apis2.ResponseOK("ok"))
}
